5.2. 구조체를 사용한 예제 프로그램
넓이 구하기 프로그램
넓이를 구하는 프로그램을 구현할 때는 가로, 세로 값이 필요할 것이다.
이 값을 묶지 않아도 되지만, 안정성을 위해서는 묶어주는 것이 좋다.
튜플로 묶게 될 경우 개발자는 가로, 세로라는 순서를 지켜야 하며 그 의미를 파악하는 것도 어렵다.
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
area(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
이렇게 해주면 값의 의미가 명확하다.
순서도 지켜야 할 필요 없다.
소유권을 가져가버리면 이후 사용할 수 없기 때문에 참조자를 활용했다.
트레이트 파생으로 유용한 기능 추가하기
구조체를 출력해보고 싶다면 어떻게 해야 하는가?
단순하게 println!을 사용하면 이러한 에러가 나온다.
:?를 추가하면 디버그 출력형식을 사용하는 방법이다.
에러 메시지를 보고 수정하면 이러한 에러가 뜬다.
우리가 만든 구조체에 디버그 기능을 넣으려면 구현을 시켜주어야만 한다.
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {:?}", rect1);
}
외부 속성을 구조체 정의 직전에 작성하여 이를 해결한다.
원래는 한 줄로 출력되지만 :#?로 바꿔주면 이렇게 줄이 바뀐다.
dbg! 매크로
Debug 포맷으로 출력하려면 dbg! 매크로를 사용하는 방법도 있다.
이것은 표현식의 소유권을 가져와 출력한 후 다시 소유권을 반환한다.
dbg!는 stderr에 출력을 진행한다.
println은 stdout에 출력한다.
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let scale = 2;
let rect1 = Rectangle {
width: dbg!(30 * scale),
height: 50,
};
dbg!(&rect1);
}
이렇게 두서 없이 사방에 dbg를 뿌리면, 해당 값의 결과를 알 수 있다.
몇번째 줄인지, 원래 값은 무엇인지도 알려준다.
참고로 구조체에 Debug 포맷을 넣어줬기에 가능한 것이다.
러스트에서는 Debug 트레이트 말고도 derive 속성으로 다양한 동작을 추가시켜줄 수 있다.